package cn.conac.as.monitor.service;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import cn.conac.as.framework.service.GenericService;
import cn.conac.as.framework.utils.StringUtils;
import cn.conac.as.framework.utils.TimestampUtils;
import cn.conac.as.monitor.entity.BdtClientMonitorEntity;
import cn.conac.as.monitor.entity.BdtVSystemInterfaceMonitorEntity;
import cn.conac.as.monitor.repository.BdtVSystemInterfaceMonitorRepository;
import cn.conac.as.monitor.util.PropertiesUtil;
import cn.conac.as.monitor.vo.BdtClientMonitorVo;
import cn.conac.as.monitor.vo.BdtVSystemInterfaceMonitorVo;

/**
 * 系统接口监控视图的服务类
 * @author lishen
 * @date	2017年7月13日上午8:43:08
 * @version 1.0
 */
@Service
public class BdtVSystemInterfaceMonitorService extends GenericService<BdtVSystemInterfaceMonitorEntity, String> {

	@Autowired
	private BdtVSystemInterfaceMonitorRepository bdtVSystemInterfaceMonitorRepository;
	
	/**
	 * 根据id查找BdtVSystemInterfaceMonitorEntity类型的对象
	 */
	public BdtVSystemInterfaceMonitorEntity findById(String id){
		return bdtVSystemInterfaceMonitorRepository.findOne(id);
	}

	/**
	 * 查找BdtVSystemInterfaceMonitorEntity对象，只包括那些性能有问题和不可用的，并且按照endTime降序排列
	 */
	public List<BdtVSystemInterfaceMonitorEntity> findBdtSystemInterfaceMonitorEntityByPerformanceAndUsability() {
		List<BdtVSystemInterfaceMonitorEntity> result = bdtVSystemInterfaceMonitorRepository
				.findAll(new Specification<BdtVSystemInterfaceMonitorEntity>() {
					@Override
					public Predicate toPredicate(Root<BdtVSystemInterfaceMonitorEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
						Predicate p = null;

						// 不可用的
						Predicate p1 = cb.isNotNull(root.get("errorInfo").as(String.class));
						p = p1;

						// 性能存在问题的
						Predicate p2 = cb.ge(root.get("responseTime").as(Double.class), new Double(PropertiesUtil
								.getValue("config/config.properties", "interface.response.warning.time")));
						if (p != null) {
							p = cb.or(p, p2);
						} else {
							p = p2;
						}
						
//						Predicate p3=cb.
						
						return p;
					}
				}, new Sort(Sort.Direction.DESC, "endTime"));

		return result;
	}
	
	/**
	 * 根据条件查找BdtVSystemInterfaceMonitorEntity对象，并且按照endTime降序排列
	 * @return
	 */
	public List<BdtVSystemInterfaceMonitorEntity> findVSystemInterfaceMonitorByCondition(final BdtVSystemInterfaceMonitorVo bdtVSystemInterfaceMonitorVo){
		List<BdtVSystemInterfaceMonitorEntity> result = bdtVSystemInterfaceMonitorRepository.findAll(new Specification<BdtVSystemInterfaceMonitorEntity>() {
			@Override
			public Predicate toPredicate(Root<BdtVSystemInterfaceMonitorEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate p = null;

				// 不可用的
				Predicate p1 = cb.isNotNull(root.get("errorInfo").as(String.class));
				p = p1;

				// 性能存在问题的
				Predicate p2 = cb.ge(root.get("responseTime").as(Double.class), new Double(PropertiesUtil
						.getValue("config/config.properties", "interface.response.warning.time")));
				if (p != null) {
					p = cb.or(p, p2);
				} else {
					p = p2;
				}
				
				// url模糊查询
				if(StringUtils.isNotEmpty(bdtVSystemInterfaceMonitorVo.getUrl())){
					Predicate p3 = cb.like(root.<String>get("url"), "%"+bdtVSystemInterfaceMonitorVo.getUrl()+"%");
	                if (p != null) {
						p = cb.and(p, p3);
					} else {
						p = p3;
					}
				}
				
				// url模糊查询
				if(StringUtils.isNotEmpty(bdtVSystemInterfaceMonitorVo.getDescription())){
					Predicate p4 = cb.like(root.<String>get("description"), "%"+bdtVSystemInterfaceMonitorVo.getDescription()+"%");
	                if (p != null) {
						p = cb.and(p, p4);
					} else {
						p = p4;
					}
				}
				
				// 开始时间和结束时间
	            if (!StringUtils.isEmpty(bdtVSystemInterfaceMonitorVo.getBeginTime()) && !StringUtils.isEmpty(bdtVSystemInterfaceMonitorVo.getFinishTime())) {
	                Timestamp beginTime=TimestampUtils.valueOf(bdtVSystemInterfaceMonitorVo.getBeginTime());
	                Timestamp finishTime=TimestampUtils.valueOf(bdtVSystemInterfaceMonitorVo.getFinishTime());
	                
	                Predicate p5 = cb.between(root.get("endTime").as(Timestamp.class), beginTime, finishTime);
	                if (p != null) {
						p = cb.and(p, p5);
					} else {
						p = p5;
					}
	            }
				
				return p;
			}
	    }, new Sort(Sort.Direction.DESC, "endTime"));

	    return result;
	}
	
	/**
	 * 根据id查找BdtVSystemInterfaceMonitorEntity对象列表，并按照降序排列
	 * @param id
	 * @return
	 */
	public List<BdtVSystemInterfaceMonitorEntity> findByIdOrderByEndTimeDesc(String id){
		return bdtVSystemInterfaceMonitorRepository.findByIdOrderByEndTimeDesc(id);
	}
	
	/**
	 * 根据interfaceId、scanTime和endTime查找BdtVSystemInterfaceMonitorEntity对象列表
	 * @param interfaceId
	 * @param scanTime
	 * @param endTime
	 * @return
	 */
	public List<BdtVSystemInterfaceMonitorEntity> findByInterfaceIdAndScanTimeAndEndTimeOrderByEndTimeAsc(final String interfaceId, final String scanTime, final String endTime){
		List<BdtVSystemInterfaceMonitorEntity> result = bdtVSystemInterfaceMonitorRepository.findAll(new Specification<BdtVSystemInterfaceMonitorEntity>() {
			@Override
			public Predicate toPredicate(Root<BdtVSystemInterfaceMonitorEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate p = null;

				// 接口id
				if(StringUtils.isNotEmpty(interfaceId)){
					Predicate p1 = cb.equal(root.get("interfaceId").as(String.class), interfaceId);
					p = p1;
				}
				
				// 开始时间和结束时间
				if(StringUtils.isNotEmpty(scanTime) && StringUtils.isNotEmpty(endTime)){
					Timestamp beginTime=TimestampUtils.valueOf(scanTime);
	                Timestamp finishTime=TimestampUtils.valueOf(endTime);
	                
	                Predicate p2 = cb.between(root.get("endTime").as(Timestamp.class), beginTime, finishTime);
	                
	                if (p != null) {
						p = cb.and(p, p2);
					} else {
						p = p2;
					}
				}
				return p;
			}
	    }, new Sort(Sort.Direction.ASC, "endTime"));

	    return result;
	}
	
	/**
	 * 根据interfaceId查找BdtVSystemInterfaceMonitorEntity对象列表
	 * @param interfaceId
	 * @return
	 */
	public List<BdtVSystemInterfaceMonitorEntity> findByInterfaceIdAndEnvironmentTypeOrderByEndTimeAsc(String interfaceId, String environmentType){
		return bdtVSystemInterfaceMonitorRepository.findByInterfaceIdAndEnvironmentTypeOrderByEndTimeAsc(interfaceId, environmentType);
	}
}
